package com.wangjiang.mario.admin.system.domain.service.impl;

import com.wangjiang.mario.admin.common.base.BaseServiceImpl;
import com.wangjiang.mario.admin.common.exception.DataScopeException;
import com.wangjiang.mario.admin.common.exception.ValidateException;
import com.wangjiang.mario.admin.common.output.MPage;
import com.wangjiang.mario.admin.common.util.CommonUtils;
import com.wangjiang.mario.admin.system.domain.entity.RoleDeptEntity;
import com.wangjiang.mario.admin.system.domain.entity.RoleEntity;
import com.wangjiang.mario.admin.system.domain.entity.RoleMenuEntity;
import com.wangjiang.mario.admin.system.domain.mapper.RoleDeptMapper;
import com.wangjiang.mario.admin.system.domain.mapper.RoleMapper;
import com.wangjiang.mario.admin.system.domain.mapper.RoleMenuMapper;
import com.wangjiang.mario.admin.system.domain.service.RoleService;
import com.wangjiang.mario.admin.system.object.role.RoleQo;
import com.wangjiang.mario.admin.system.object.role.RoleVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleEntity>
        implements RoleService {

    private static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);

    // 自定义数据权限
    public static final String DATA_SCOPE_CUSTOM = "2";

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private RoleDeptMapper roleDeptMapper;

    @Override
    public MPage basePageWithDept(Integer currentPage, Integer pageSize, RoleQo qo, Class<RoleVo> roleVoClass) {
        MPage<RoleEntity> page = basePage(currentPage, pageSize, qo, roleVoClass);
        // 获取所有的角色的部门列表并装配到结果中
        List<RoleVo> list = page.getContent();
        List<String> roleCodeList = list.stream().map(RoleVo::getCode).collect(Collectors.toList());
        if (roleCodeList.size() > 0) {
            // 获取所有角色部门关联数据
            List<RoleDeptEntity> roleDeptEntities = roleDeptMapper.selectListByRoleCodeList(roleCodeList);
            // 组合成 roleCode 为key的map deptCode 为value的map
            Map<String, List<String>> roleDeptMap = new HashMap<>();
            Map<String, List<RoleDeptEntity>> map = roleDeptEntities.stream().collect(Collectors.groupingBy(RoleDeptEntity::getRoleCode));
            for (Map.Entry<String, List<RoleDeptEntity>> entry : map.entrySet()) {
                String roleCode = entry.getKey();
                List<RoleDeptEntity> deptList = entry.getValue();
                List<String> deptCodeList = deptList.stream().map(RoleDeptEntity::getDeptCode).collect(Collectors.toList());
                roleDeptMap.put(roleCode, deptCodeList);
            }
            // 组合数据到list总
            for (RoleVo role : list) {
                // 如果有该角色的部门关联数据，则赋值进去
                if(roleDeptMap.containsKey(role.getCode())){
                    role.setDeptList(roleDeptMap.get(role.getCode()));
                }
            }
        }
        return page;
    }


    /**
     * 为角色保存菜单权限
     *
     * @param roleCode
     * @param menuCodes
     * @return rows 行数
     */
    @Override
    public Integer setRoleMenu(String roleCode, List<String> menuCodes) {
        if (CommonUtils.isNull(menuCodes)) {
            throw new ValidateException("没有菜单id传入");
        }
        List roleMenuList = new ArrayList<>();
        for (String menuCode : menuCodes) {
            RoleMenuEntity roleMenuEntity = new RoleMenuEntity();
            roleMenuEntity.setMenuCode(menuCode);
            roleMenuEntity.setRoleCode(roleCode);
            roleMenuList.add(roleMenuEntity);
        }
        Integer rows = roleMenuMapper.batchInsertRoleMenus(roleMenuList);
        return rows;
    }

    /**
     * 为角色保存菜单权限
     *
     * @param roleCode
     * @param menuCodes
     * @return rows 行数
     */
    @Override
    public Integer updateRoleMenu(String roleCode, List<String> menuCodes) {
        if (CommonUtils.isNull(menuCodes)) {
            throw new ValidateException("没有菜单id传入");
        }
        roleMenuMapper.deleteRoleMenuByRoleCode(roleCode);
        return setRoleMenu(roleCode, menuCodes);
    }

    /**
     * 获取某个角色的所有菜单code列表
     *
     * @param roleCode
     * @return
     */
    @Override
    public List<String> getMenusByRoleCode(String roleCode) {
        List<String> list = roleMenuMapper.getMenusByRoleCode(roleCode);
        return list;
    }

    /**
     * 保存角色
     *
     * @param roleEntity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveRole(RoleEntity roleEntity) {
        // 自定义角色权限 需要绑定部门列表
        if (Objects.equals(roleEntity.getDataScope(), DATA_SCOPE_CUSTOM)) {
            // 如果部门列表为空，抛出异常
            if (roleEntity.getDeptList().length < 1) {
                throw new DataScopeException("缺少部门设定");
            } else {
                // 保存角色部门关系
                List<RoleDeptEntity> roleDeptEntities = new ArrayList<>();
                for (String deptCode : roleEntity.getDeptList()) {
                    RoleDeptEntity roleDept = new RoleDeptEntity();
                    roleDept.setDeptCode(deptCode);
                    roleDept.setRoleCode(roleEntity.getCode());
                    roleDeptEntities.add(roleDept);
                }
                // 删除旧数据，插入新数据
                roleDeptMapper.deleteRoleDeptByRoleCode(roleEntity.getCode());
                roleDeptMapper.batchInsertRoleDepts(roleDeptEntities);
            }
        }

        return baseSave(roleEntity);
    }
}
